﻿
Imports std

'this is not a good design to make data be in language itself
Public Class foreach
    Inherits sentence

    Public Const foreach As String = "foreach"
    Public Const [each] As String = "each"
    Public Const for_each As String = "for each"
    Public Const [in] As String = "in"

    Private name As String = Nothing
    Private dataset As String = Nothing
    Private para As paragraph = Nothing

    Private Sub New(ByVal name As String, ByVal dataset As String, ByVal para As paragraph)
        Me.name = name
        Me.dataset = dataset
        Me.para = para
    End Sub

    Protected Friend Shared Shadows Function _isMeaningfulMark(ByVal c As Char) As Boolean
        Return False
    End Function

    Private Class iteratorcb
        Public Class v
            Inherits vd_t(Of variable)

            Public Overrides Function cb(Of T)(ByRef i As vector(Of T), ByRef rtn As variable, _
                                               ByVal ET As typeDefination, _
                                               ByVal ParamArray para() As Object) As Boolean
                rtn = New variable(ET, typeDefination.unknown, typeDefination.unknown)
                Return True
            End Function
        End Class

        Public Class s
            Inherits sd_t(Of variable)

            Public Overrides Function cb(Of T As IComparable(Of T))(ByRef i As [set](Of T), _
                                                                    ByRef rtn As variable, _
                                                                    ByVal ET As typeDefination, _
                                                                    ByVal ParamArray para() As Object) As Boolean
                rtn = New variable(ET, typeDefination.unknown, typeDefination.unknown)
                Return True
            End Function
        End Class

        Public Class l
            Inherits ld_t(Of variable)

            Public Overrides Function cb(Of T)(ByRef i As list(Of T), ByRef rtn As variable, _
                                               ByVal ET As typeDefination, _
                                               ByVal ParamArray para() As Object) As Boolean
                rtn = New variable(ET, typeDefination.unknown, typeDefination.unknown)
                Return True
            End Function
        End Class

        Public Class m
            Inherits md_t(Of variable)

            Public Overrides Function cb(Of T As IComparable(Of T), T2)(ByRef i As map(Of T, T2), _
                                                                        ByRef rtn As variable, _
                                                                        ByVal ET1 As typeDefination, _
                                                                        ByVal ET2 As typeDefination, _
                                                                        ByVal ParamArray para() As Object) As Boolean
                rtn = New variable(ET2, typeDefination.unknown, typeDefination.unknown)
                Return True
            End Function
        End Class

        Public Shared vcb As v = Nothing
        Public Shared scb As s = Nothing
        Public Shared lcb As l = Nothing
        Public Shared mcb As m = Nothing

        Shared Sub New()
            vcb = New v()
            scb = New s()
            lcb = New l()
            mcb = New m()
        End Sub
    End Class

    Private Class cbpara
        Public itv As pointer(Of bare_variable) = Nothing
        Public para As paragraph = Nothing
        Public ctx As context = Nothing

        Public Sub New(ByVal itv As pointer(Of bare_variable), ByVal para As paragraph, ByVal ctx As context)
            Me.itv = itv
            Me.para = para
            Me.ctx = ctx
        End Sub
    End Class

    Private Class loopcb
        Public Class v
            Inherits vd_t(Of Boolean)

            Private Function cbImp(Of T)(ByVal i As vector(Of T), ByVal itv As pointer(Of bare_variable), _
                                         ByVal para As paragraph, ByVal ctx As context, ByRef rtn As Boolean) As Boolean
                Dim j As Int64
                For j = 0 To i.size() - 1
                    With +itv
                        .setvalue(i(j))
                    End With
                    para.invoke(ctx)
                Next
                rtn = True
                Return True
            End Function

            Protected Overrides Function cb(Of T)(ByRef i As vector(Of T), _
                                                  ByRef rtn As Boolean, _
                                                  ByVal ParamArray ps() As Object) As Boolean
                Dim para As cbpara = Nothing
                para = paramarray_get(Of cbpara)(0, ps)
                Return cbImp(i, para.itv, para.para, para.ctx, rtn)
            End Function
        End Class

        Public Class s
            Inherits sd_t(Of Boolean)

            Private Function cbImp(Of T As IComparable(Of T))(ByVal i As [set](Of T), _
                                                              ByVal itv As pointer(Of bare_variable), _
                                                              ByVal para As paragraph, ByVal ctx As context, _
                                                              ByRef rtn As Boolean) As Boolean
                Dim it As [set](Of T).iterator = Nothing
                it = i.begin()
                While it <> i.end()
                    With +itv
                        .setvalue(+it)
                    End With
                    para.invoke(ctx)
                    it += 1
                End While
                rtn = True
                Return True
            End Function

            Protected Overrides Function cb(Of T As IComparable(Of T)) _
                                           (ByRef i As [set](Of T), _
                                            ByRef rtn As Boolean, _
                                            ByVal ParamArray ps() As Object) As Boolean
                Dim para As cbpara = Nothing
                para = paramarray_get(Of cbpara)(0, ps)
                Return cbImp(i, para.itv, para.para, para.ctx, rtn)
            End Function
        End Class

        Public Class l
            Inherits ld_t(Of Boolean)

            Private Function cbImp(Of T)(ByVal i As list(Of T), ByVal itv As pointer(Of bare_variable), _
                                         ByVal para As paragraph, ByVal ctx As context, _
                                         ByRef rtn As Boolean) As Boolean
                Dim it As list(Of T).iterator = Nothing
                it = i.begin()
                While it <> i.end()
                    With +itv
                        .setvalue(+it)
                    End With
                    para.invoke(ctx)
                    it += 1
                End While
                rtn = True
                Return True
            End Function

            Protected Overrides Function cb(Of T)(ByRef i As list(Of T), ByRef rtn As Boolean, _
                                                  ByVal ParamArray ps() As Object) As Boolean
                Dim para As cbpara = Nothing
                para = paramarray_get(Of cbpara)(0, ps)
                Return cbImp(i, para.itv, para.para, para.ctx, rtn)
            End Function
        End Class

        Public Class m
            Inherits md_t(Of Boolean)

            Private Function cbImp(Of T As IComparable(Of T), T2)(ByVal i As map(Of T, T2), _
                                                                  ByVal itv As pointer(Of bare_variable), _
                                                                  ByVal para As paragraph, ByVal ctx As context, _
                                                                  ByRef rtn As Boolean) As Boolean
                Dim it As map(Of T, T2).iterator = Nothing
                it = i.begin()
                While it <> i.end()
                    With +itv
                        .setvalue((+it).first())
                    End With
                    para.invoke(ctx)
                    it += 1
                End While
                rtn = True
                Return True
            End Function

            Protected Overrides Function cb(Of T As IComparable(Of T), T2) _
                                           (ByRef i As map(Of T, T2), _
                                            ByRef rtn As Boolean, _
                                            ByVal ParamArray ps() As Object) As Boolean
                Dim para As cbpara = Nothing
                para = paramarray_get(Of cbpara)(0, ps)
                Return cbImp(i, para.itv, para.para, para.ctx, rtn)
            End Function
        End Class

        Public Shared vcb As v = Nothing
        Public Shared scb As s = Nothing
        Public Shared lcb As l = Nothing
        Public Shared mcb As m = Nothing

        Shared Sub New()
            vcb = New v()
            scb = New s()
            lcb = New l()
            mcb = New m()
        End Sub
    End Class

    Protected Overrides Function invokeImpl(ByVal ctx As context) As Boolean
        Dim itv As variable = Nothing
        Dim datasetv As bare_variable = Nothing
        If ctx.findVariable(dataset, datasetv) Then
            If datasetv.invoke(itv, iteratorcb.mcb, iteratorcb.vcb, iteratorcb.scb, iteratorcb.lcb) Then
                Dim o As Object = Nothing
                If itv.invoke(o) Then
                    Dim itbv As bare_variable = Nothing
                    itbv = New bare_variable(itv, o)
                    Dim it As variables_t.iterator = Nothing
                    it = ctx.insertVariable(name, itbv)
                    If it <> ctx.variables_end() Then
                        If datasetv.invoke(loopcb.mcb, loopcb.vcb, loopcb.scb, loopcb.lcb, _
                                           New cbpara(New pointer(Of bare_variable) _
                                                                 ((+it).second), para, ctx)) Then
                            Return True
                        Else
                            Return False
                        End If
                    Else
                        Return False
                    End If
                Else
                    Return False
                End If
            Else
                Return False
            End If
        Else
            raiseError("expect variable " + dataset, errorHandle.errorType.user)
            Return False
        End If
    End Function

    Private Shared Function foreachstart(ByVal s As String, ByVal index As Int64, ByRef inc As Int64) As Boolean
        If strsame(s, index, foreach, 0, strlen(foreach)) Then
            inc = strlen(foreach)
            Return True
        ElseIf strsame(s, index, [each], 0, strlen([each])) Then
            inc = strlen([each])
            Return True
        ElseIf strsame(s, index, for_each, 0, strlen(for_each)) Then
            inc = strlen(for_each)
            Return True
        Else
            Return False
        End If
    End Function

    Private Shared Function foreachin(ByVal s As String, ByVal index As Int64, ByRef inc As Int64) As Boolean
        If strsame(s, index, [in], 0, strlen([in])) Then
            inc = strlen([in])
            Return True
        Else
            Return False
        End If
    End Function

    Protected Shared Function parseImpl(ByVal input As String, ByRef index As Int64, _
                                        ByRef output As foreach) As Boolean
       If token(input, index, Nothing, AddressOf foreachstart, AddressOf [false]) Then
            Dim name As String = Nothing
            If value_name_defination.parse(input, index, name) Then
                If token(input, index, Nothing, AddressOf foreachin, AddressOf [false]) Then
                    Dim dataset As String = Nothing
                    If value_name_defination.parse(input, index, dataset) Then
                        Dim para As paragraph = Nothing
                        If paragraph.parse(input, index, para) Then
                            output = New foreach(name, dataset, para)
                            Return True
                        Else
                            Return False
                        End If
                    Else
                        Return False
                    End If
                Else
                    Return False
                End If
            Else
                Return False
            End If
        Else
            Return False
        End If
    End Function

    Protected Overrides Sub setsource(ByVal script As String, ByVal start As Long, ByVal [end] As Long)
        setsourceImpl(foreach + character.blank + name + character.blank + [in] + character.blank + dataset, _
                      start, [end])
    End Sub

    Public Shared Shadows Function parse(ByVal input As String, ByRef index As Int64, _
                                         ByRef output As foreach) As Boolean
        Return parsebase(input, index, output, AddressOf parseImpl)
    End Function
End Class
